package com.hunan.yllxy.config.security;

import com.hunan.yllxy.repostitory.dao.RoleDao;
import com.hunan.yllxy.repostitory.dao.UserInfoDao;
import com.hunan.yllxy.repostitory.dao.UserRoleDao;
import com.hunan.yllxy.repostitory.entity.Role;
import com.hunan.yllxy.repostitory.entity.UserInfo;
import com.hunan.yllxy.util.JwtUtils;
import io.jsonwebtoken.Claims;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import org.springframework.web.servlet.HandlerExceptionResolver;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Component
public class JwtAuthencationTokenFilter extends OncePerRequestFilter {
    @Autowired
    UserInfoDao userInfoDao;
    @Autowired
    UserRoleDao userRoleDao;
    @Autowired
    RoleDao roleDao;

    @Autowired
    @Qualifier("handlerExceptionResolver")
    private HandlerExceptionResolver resolver;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        try{
            String authHeader = request.getHeader("token");
            //存在token
            Claims claims = JwtUtils.parseJwt(authHeader);
            Date expiration = claims.getExpiration();
            if(expiration.getTime() < new Date().getTime()){
                //过期
                filterChain.doFilter(request, response);
                return;
            }
            String username = claims.getSubject();
            UserInfo byAccount = userInfoDao.findByAccount(username);
            if(byAccount == null){
                //token 非法
                filterChain.doFilter(request, response);
                return;
            }

            String userInfoId = byAccount.getId();
            List<String> roleIds = userRoleDao.findByUserId(userInfoId);
            List<SimpleGrantedAuthority> authorities = new ArrayList<>();
            if(roleIds.size()>0){
                List<Role> roles = roleDao.findByIds(roleIds);
                for (Role role : roles) {
                    String name = role.getName();
                    SimpleGrantedAuthority authority = new SimpleGrantedAuthority(name);
                    authorities.add(authority);
                }
            }

            UsernamePasswordAuthenticationToken authenticationToken =
                    new UsernamePasswordAuthenticationToken(byAccount, null,authorities );
            authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
            SecurityContextHolder.getContext().setAuthentication(authenticationToken);
            String token = JwtUtils.createJwt(username, byAccount.getId(), 1000 * 60 * 60 *6 );
            response.setHeader("token",token);
            response.setHeader("Access-Control-Expose-Headers", "token");
            filterChain.doFilter(request, response);
        }catch (Exception e){
//            e.printStackTrace();
            filterChain.doFilter(request, response);
        }


    }
}
